/* http://plugins.jquery.com/files/jquery.floatobject-1.4.js.txt */

(function($){
/*----------------------------------------------------------------------------------
Class: FloatObject
-------------------------------------------------------------------------------------*/
   function FloatObject(jqObj, params)
   {
      this.jqObj = jqObj;
      
      switch(params.speed)
      {
         case 'fast': this.steps = 5; break;
         case 'normal': this.steps = 10; break;
         case 'slow': this.steps = 20; break;
         default: this.steps = 10;
      };
      
      var offset = this.jqObj.offset();
      this.currentX = offset.left;
      this.currentY = offset.top;
      this.width = this.jqObj.width();
      this.height = this.jqObj.height();
      this.alwaysVisible = params.alwaysVisible;
      this.alwaysTop = params.alwaysTop;
      
      
      this.origX = typeof(params.x) == "string" ?  this.currentX : params.x;
      this.origY = typeof(params.y) == "string" ?  this.currentY : params.y;
            
      
      //now we make sure the object is in absolute positions.
      this.jqObj.css({'position':'absolute' , 'top':this.currentY ,'left':this.currentX});
   }
   
   FloatObject.prototype.updateLocation = function()
   {
      this.updatedX = $(window).scrollLeft() + this.origX;
      
      if( this.alwaysTop == false ){
         this.updatedY = $(window).scrollTop()+ this.origY;
         
         if( this.alwaysVisible ){
            if( this.origX + this.width > this.windowWidth() ) 
               this.updatedX = this.windowWidth() - this.width + $(window).scrollLeft();
            if( this.origY + this.height > this.windowHeight() ) 
            {
               this.updatedY = $(window).scrollTop() + this.windowHeight() - this.height;
               if( this.updatedY < this.origY ) this.updatedY = this.origY;
            }           
         }
      }
      else
      {

         if( $(window).scrollTop() > this.origY )
         {
            this.updatedY = $(window).scrollTop() + 5;
         }
         else
         {
            this.updatedY = this.origY + 5;
         }
      }
      this.dx = Math.abs(this.updatedX - this.currentX );
      this.dy = Math.abs(this.updatedY - this.currentY );
      
      return this.dx || this.dy;
   }
   
   FloatObject.prototype.windowHeight = function()
   {
      var de = document.documentElement;
      
      return self.innerHeight ||
         (de && de.clientHeight) ||
         document.body.clientHeight;
   }
   
   FloatObject.prototype.windowWidth = function()
   {
      var de = document.documentElement;
      
      return self.innerWidth ||
         (de && de.clientWidth) ||
         document.body.clientWidth;
   }
   
   
   FloatObject.prototype.move = function()
   {
      if( this.jqObj.css("position") != "absolute" ) return;
      var cx = 0;
      var cy = 0;
      
      if( this.dx > 0 )
      {        
         if( this.dx < this.steps / 2 )
            cx = (this.dx >= 1) ? 1 : 0;
         else
            cx = Math.round(this.dx/this.steps);
         
         if( this.currentX < this.updatedX )
            this.currentX += cx;
         else
            this.currentX -= cx;
      }
      
      if( this.dy > 0 )
      {
         if( this.dy < this.steps / 2 )
            cy = (this.dy >= 1) ? 1 : 0;
         else
            cy = Math.round(this.dy/this.steps);
         
         if( this.currentY < this.updatedY )
            this.currentY += cy;
         else
            this.currentY -= cy;
      }
      
      this.jqObj.css({'left':this.currentX, 'top': this.currentY });       
   }

   
   
/*----------------------------------------------------------------------------------
Object: floatMgr
-------------------------------------------------------------------------------------*/      
   $.floatMgr = {
      
      FOArray: new Array() ,
      
      timer: null ,
      
      initializeFO: function(jqObj,params) 
      {
         var settings =  $.extend({
            x: 0 ,
            y: 0 ,
            speed: 'normal'   ,
            alwaysVisible: false ,
            alwaysTop: false},params||{});
         var newFO = new FloatObject(jqObj,settings);
         
         $.floatMgr.FOArray.push(newFO);
         
         if( !$.floatMgr.timer ) $.floatMgr.adjustFO();
         
         //now making sure we are registered to all required window events
         if( !$.floatMgr.registeredEvents ) 
         {
               $(window).bind("resize", $.floatMgr.onChange);
               $(window).bind("scroll", $.floatMgr.onChange);
               $.floatMgr.registeredEvents = true;
         }     
      } , 
      
      adjustFO: function() 
      {
         $.floatMgr.timer = null;
         
         var moveFO = false;
         
         for( var i = 0 ; i < $.floatMgr.FOArray.length ; i++ )
         {
             FO = $.floatMgr.FOArray[i];
             if( FO.updateLocation() )  moveFO = true;
         }
         
         if( moveFO )
         {
            for( var i = 0 ; i < $.floatMgr.FOArray.length ; i++ )
            {
               FO = $.floatMgr.FOArray[i];
               FO.move();
            }
            
            if( !$.floatMgr.timer ) $.floatMgr.timer = setTimeout($.floatMgr.adjustFO,50);
         }
      }  ,
      
      stopFloatChk: false ,
      
      onChange: function()
      {
         if( !$.floatMgr.timer && !$.floatMgr.stopFloatChk ) $.floatMgr.adjustFO();
      }     
   };
   
/*----------------------------------------------------------------------------------
Function: makeFloat
-------------------------------------------------------------------------------------*/      
   $.fn.makeFloat = function(params) {
      var obj = this.eq(0); //we only operate on the first selected object;
      $.floatMgr.initializeFO(obj,params); 
      if( $.floatMgr.timer == null ) $.floatMgr.adjustFO();
      return obj;
   };
   $.fn.stopFloat = function(params) {
      $.floatMgr.stopFloatChk = true;
   };
   
   $.fn.restartFloat = function(params) {
      $.floatMgr.stopFloatChk = false;
   };
})(jQuery);
